#include "gtest/gtest.h"
#include "Logger.h"
#include "Exception.h"

USING_NS_B2D

class TestLoggerOutput : public ILoggerOutput
{
public:
	unsigned count;
	TestLoggerOutput(void) : count(false) { }
	void log(LogLevel level, const string& msg, const string& file, int line, const string& function)
	{
		++count;
	}
};

class StupidLoggerOutput : public ILoggerOutput
{
	TestLoggerOutput output;
	void log(LogLevel level, const string& msg, const string& file, int line, const string& function)
	{
		Logger::Get().registerOutput(output);
	}
};

TEST(test_logger, output_registering)
{
	Logger logger;
	TestLoggerOutput output;

	size_t countStart = logger.getOutputCount();
	logger.registerOutput(output);
	size_t countReg = logger.getOutputCount();
	logger.unregisterOutput(output);
	size_t countUnreg = logger.getOutputCount();

	EXPECT_EQ(0, countStart);
	EXPECT_EQ(1, countReg);
	EXPECT_EQ(0, countUnreg);
}

TEST(test_logger, output_receives_logs)
{
	Logger logger;
	TestLoggerOutput output;
	logger.registerOutput(output);

	size_t countBefore = output.count;
	B2D_LOG_DEBUG0("");
	size_t countAfter = output.count;

	EXPECT_EQ(0, countBefore);
	EXPECT_EQ(1, countAfter);
}

TEST(test_logger, register_too_many_outputs)
{
	Logger logger;
	TestLoggerOutput output[Logger::MAX_OUTPUTS+1];

	for(size_t i = 0; i < Logger::MAX_OUTPUTS; ++i)
		logger.registerOutput(output[i]);

	bool exceptionThrown = false;
	try
	{
		logger.registerOutput(output[Logger::MAX_OUTPUTS]);
	}
	catch(...)
	{
		exceptionThrown = true;
	}

	EXPECT_EQ(true, exceptionThrown);
}

TEST(test_logger, register_during_log)
{
	Logger logger;
	StupidLoggerOutput output;

	size_t countStart = logger.getOutputCount();
	logger.registerOutput(output);
	size_t countReg = logger.getOutputCount();
	B2D_LOG0(LogLevel::LOG_WARNING, "");
	size_t countLog = logger.getOutputCount();

	EXPECT_EQ(0, countStart);
	EXPECT_EQ(1, countReg);
	EXPECT_EQ(2, countLog);
}